package com.example.library;

import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Body;
import retrofit2.http.POST;
import retrofit2.http.Headers;
import com.google.gson.annotations.SerializedName;
import com.google.gson.GsonBuilder;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import okhttp3.ResponseBody;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import java.util.concurrent.TimeUnit;
import android.util.Log;
import com.google.gson.Gson;
import java.io.IOException;
import org.json.JSONObject;
import java.util.Arrays;
import okhttp3.Protocol;
import android.text.TextUtils;
import okhttp3.Request;
import java.util.Map;
import java.util.HashMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.Field;
import com.google.gson.JsonObject;

public class ApiService {
    private static final String BASE_URL = "http://47.97.164.216:8080/";
    private static final String TAG = "ApiService";
    private static ApiService instance;
    private final ApiInterface api;
    private final Gson gson;

    private ApiService() {
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.d(TAG, "OkHttp: " + message);
            }
        });
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(logging)
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .protocols(Arrays.asList(Protocol.HTTP_1_1))
                .build();

        gson = new GsonBuilder()
                .setLenient()
                .create();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
        api = retrofit.create(ApiInterface.class);
    }

    public static synchronized ApiService getInstance() {
        if (instance == null) {
            instance = new ApiService();
        }
        return instance;
    }

    // API响应数据类
    public static class ApiResponse {
        @SerializedName("code")
        public int code;
        @SerializedName("msg")
        public String msg;
        @SerializedName("data")
        public Object data;
    }

    // 登录请求数据类
    public static class LoginRequest {
        @SerializedName("account")
        private String account;
        @SerializedName("password")
        private String password;
        @SerializedName("type")
        private String type;

        public LoginRequest(String account, String password, String type) {
            this.account = account;
            this.password = password;
            this.type = type;
        }
    }

    // 注册请求数据类
    public static class RegisterRequest {
        @SerializedName("account")
        private String account;
        @SerializedName("password")
        private String password;
        @SerializedName("type")
        private String type;

        public RegisterRequest(String account, String password, String type) {
            this.account = account;
            this.password = password;
            this.type = type;
        }
    }

    // API接口定义
    private interface ApiInterface {
        @Headers({
            "Content-Type: application/json",
            "Accept: application/json",
            "Cache-Control: no-cache",
            "User-Agent: Android-Library-App",
            "Connection: keep-alive"
        })
        @POST("api/user/register")
        Call<ResponseBody> register(@Body JsonObject request);

        @Headers({
            "Content-Type: application/json",
            "Accept: application/json",
            "Cache-Control: no-cache",
            "User-Agent: Android-Library-App",
            "Connection: keep-alive"
        })
        @POST("api/user/login")
        Call<ResponseBody> login(@Body JsonObject request);
    }

    // 登录方法
    public void login(String id, String password, String userType, final Callback callback) {
        try {
            // 输入验证
            if (TextUtils.isEmpty(id) || id.length() < 4 || id.length() > 20) {
                callback.onFailure("账号长度必须在4-20位之间");
                return;
            }
            if (TextUtils.isEmpty(password) || password.length() < 6 || password.length() > 20) {
                callback.onFailure("密码长度必须在6-20位之间");
                return;
            }
            if (TextUtils.isEmpty(userType)) {
                callback.onFailure("请选择正确的身份类型");
                return;
            }

            // 确保用户类型正确转换
            String type;
            if ("学生".equals(userType)) {
                type = "student";
            } else if ("管理员".equals(userType)) {
                type = "admin";
            } else {
                callback.onFailure("无效的用户类型，请选择学生或管理员");
                return;
            }
            
            // 创建JSON请求体
            JsonObject jsonRequest = new JsonObject();
            String username = id.toLowerCase().trim();
            jsonRequest.addProperty("username", username);
            jsonRequest.addProperty("password", password.trim());
            jsonRequest.addProperty("type", type);
            
            Log.d(TAG, "开始登录请求...");
            Log.d(TAG, "登录请求URL: " + BASE_URL + "api/user/login");
            Log.d(TAG, "登录请求参数:");
            Log.d(TAG, "- username: " + username);
            Log.d(TAG, "- password: " + password.replaceAll(".", "*")); // 密码打码显示
            Log.d(TAG, "- type: " + type);

            api.login(jsonRequest).enqueue(new retrofit2.Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
                    try {
                        Log.d(TAG, "收到登录响应");
                        Log.d(TAG, "登录响应代码: " + response.code());
                        String responseString = response.body() != null ? response.body().string() : null;
                        Log.d(TAG, "登录原始响应: " + responseString);

                        if (response.isSuccessful()) {
                            Log.d(TAG, "登录请求成功处理响应");
                            if (responseString != null) {
                                // 尝试解析响应
                                try {
                                    JSONObject jsonResponse = new JSONObject(responseString);
                                    int code = jsonResponse.optInt("code", -1);
                                    String msg = jsonResponse.optString("msg", "");
                                    
                                    if (code == 200) {
                                        // 检查返回的用户数据中的type是否匹配
                                        if (jsonResponse.has("data")) {
                                            JSONObject userData = jsonResponse.getJSONObject("data");
                                            String userType = userData.optString("type", "");
                                            String loginType = type; // 这是登录时传入的type
                                            
                                            if (!TextUtils.isEmpty(userType) && !userType.equals(loginType)) {
                                                // 身份类型不匹配
                                                Log.e(TAG, "身份类型不匹配 - 数据库类型: " + userType + ", 登录类型: " + loginType);
                                                callback.onFailure("身份类型不匹配，您是" + 
                                                    ("admin".equals(userType) ? "管理员" : "学生") + 
                                                    "账号，请使用正确的身份类型登录");
                                                return;
                                            }
                                        }
                                        callback.onSuccess(msg);
                                    } else if (code == 403) {
                                        // 身份验证失败
                                        callback.onFailure("身份类型不匹配，请使用正确的身份类型登录");
                                    } else if (code == 401) {
                                        // 用户名或密码错误
                                        callback.onFailure("用户名或密码错误");
                                    } else {
                                        // 其他错误
                                        callback.onFailure(msg);
                                    }
                                } catch (Exception e) {
                                    // 如果不是JSON格式，直接判断响应内容
                                    if (responseString.contains("身份类型不匹配")) {
                                        callback.onFailure("身份类型不匹配，请使用正确的身份类型登录");
                                    } else if (responseString.contains("成功")) {
                                        callback.onSuccess(responseString);
                                    } else {
                                        callback.onFailure(responseString);
                                    }
                                }
                            } else {
                                callback.onFailure("登录失败: 服务器没有返回数据");
                            }
                        } else {
                            String errorBody = response.errorBody() != null ? 
                                response.errorBody().string() : "未知错误";
                            Log.e(TAG, "Login error body: " + errorBody);
                            callback.onFailure("登录失败: " + errorBody);
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "Login response parsing error", e);
                        callback.onFailure("登录失败: " + e.getMessage());
                    }
                }

                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {
                    Log.e(TAG, "Login network error", t);
                    callback.onFailure("网络错误: " + t.getMessage());
                }
            });
        } catch (Exception e) {
            Log.e(TAG, "Login request creation error", e);
            callback.onFailure("创建请求失败: " + e.getMessage());
        }
    }

    // 注册方法
    public void register(String name, String id, String password, String contact, String userType, final Callback callback) {
        try {
            // 输入验证
            if (TextUtils.isEmpty(id) || id.length() < 4 || id.length() > 20) {
                callback.onFailure("账号长度必须在4-20位之间");
                return;
            }
            if (TextUtils.isEmpty(password) || password.length() < 6 || password.length() > 20) {
                callback.onFailure("密码长度必须在6-20位之间");
                return;
            }
            if (TextUtils.isEmpty(name)) {
                callback.onFailure("姓名不能为空");
                return;
            }

            String type = "学生".equals(userType) ? "student" : "admin";
            
            // 创建与数据库结构匹配的JSON请求体
            JsonObject jsonRequest = new JsonObject();
            jsonRequest.addProperty("username", id.toLowerCase().trim()); // 使用username而不是account
            jsonRequest.addProperty("password", password.trim());
            jsonRequest.addProperty("type", type);
            // name字段可以为null，所以不强制添加
            if (!TextUtils.isEmpty(name)) {
                jsonRequest.addProperty("name", name.trim());
            }
            
            String requestJson = jsonRequest.toString();
            Log.d(TAG, "===============================================");
            Log.d(TAG, "开始发送注册请求");
            Log.d(TAG, "注册请求URL: " + BASE_URL + "api/user/register");
            Log.d(TAG, "注册请求体: " + requestJson);
            Log.d(TAG, "注册请求参数:");
            Log.d(TAG, "- account: " + id.toLowerCase());
            Log.d(TAG, "- password: " + password.replaceAll(".", "*")); // 密码打码显示
            Log.d(TAG, "- type: " + type);
            Log.d(TAG, "- name: " + name);
            if (!TextUtils.isEmpty(contact)) {
                Log.d(TAG, "- contact: " + contact);
            }
            Log.d(TAG, "===============================================");

            api.register(jsonRequest).enqueue(new retrofit2.Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
                    try {
                        Log.d(TAG, "===============================================");
                        Log.d(TAG, "收到注册响应");
                        Log.d(TAG, "注册响应代码: " + response.code());
                        String responseString = response.body() != null ? response.body().string() : null;
                        Log.d(TAG, "注册原始响应: " + responseString);
                        Log.d(TAG, "响应头: " + response.headers());
                        Log.d(TAG, "===============================================");

                        if (response.isSuccessful()) {
                            Log.d(TAG, "注册HTTP请求成功，开始处理响应");
                            if (responseString != null) {
                                // 尝试解析响应
                                try {
                                    JSONObject jsonResponse = new JSONObject(responseString);
                                    int code = jsonResponse.optInt("code", -1);
                                    String msg = jsonResponse.optString("msg", "");
                                    Log.d(TAG, "解析JSON响应 - code: " + code + ", msg: " + msg);
                                    
                                    if (code == 200) {
                                        callback.onSuccess(msg);
                                    } else {
                                        callback.onFailure(msg);
                                    }
                                } catch (Exception e) {
                                    Log.d(TAG, "响应不是JSON格式，作为普通文本处理: " + responseString);
                                    // 如果不是JSON格式，直接使用返回的字符串
                                    if (responseString.contains("成功")) {
                                        callback.onSuccess(responseString);
                                    } else {
                                        callback.onFailure(responseString);
                                    }
                                }
                            } else {
                                Log.e(TAG, "注册失败: 服务器返回空响应");
                                callback.onFailure("注册失败: 服务器没有返回数据");
                            }
                        } else {
                            String errorBody = response.errorBody() != null ? 
                                response.errorBody().string() : "未知错误";
                            Log.e(TAG, "注册HTTP请求失败 - HTTP状态码: " + response.code());
                            Log.e(TAG, "错误响应体: " + errorBody);
                            Log.e(TAG, "错误响应头: " + response.headers());
                            
                            // 尝试解析错误信息
                            try {
                                JSONObject errorJson = new JSONObject(errorBody);
                                String errorMessage = errorJson.optString("message", "");
                                if (TextUtils.isEmpty(errorMessage)) {
                                    errorMessage = errorJson.optString("error", "未知错误");
                                }
                                callback.onFailure("注册失败: " + errorMessage);
                            } catch (Exception e) {
                                callback.onFailure("注册失败: " + errorBody);
                            }
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "注册响应处理错误", e);
                        Log.e(TAG, "错误详情: " + e.getMessage());
                        Log.e(TAG, "错误堆栈: ", e);
                        callback.onFailure("注册失败: " + e.getMessage());
                    }
                }

                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {
                    Log.e(TAG, "注册网络请求错误", t);
                    Log.e(TAG, "请求URL: " + call.request().url());
                    Log.e(TAG, "错误类型: " + t.getClass().getSimpleName());
                    Log.e(TAG, "错误信息: " + t.getMessage());
                    Log.e(TAG, "错误堆栈: ", t);
                    callback.onFailure("网络错误: " + t.getMessage());
                }
            });
        } catch (Exception e) {
            Log.e(TAG, "创建注册请求时发生错误", e);
            Log.e(TAG, "错误详情: " + e.getMessage());
            Log.e(TAG, "错误堆栈: ", e);
            callback.onFailure("创建请求失败: " + e.getMessage());
        }
    }

    // 回调接口
    public interface Callback {
        void onSuccess(String result);
        void onFailure(String error);
    }
} 